package com.youyun56.com.gps;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import javax.sql.DataSource;

import org.apache.commons.dbcp.BasicDataSourceFactory;
import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator;

import com.j3.db.ConnectionManager;
import com.j3.db.DataSourceUnRegisterException;
import com.j3.sql.GridUtils;
import com.j3.sql.SqlFunc;

class Car {
    public Car(int id, String position) {
        // TODO Auto-generated constructor stub
        this.id = id;
        this.position = position;
    }

    private Integer id;
    private String position;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getPosition() {
        return position;
    }

    public void setPosition(String position) {
        this.position = position;
    }

}

public class AnalysisCarCurrentCity implements Runnable {

    public List<Car> cars = new ArrayList<Car>();
    public Hashtable<Integer, String> citys = new Hashtable<Integer, String>();
    private final static Logger log = Logger.getLogger(AnalysisCarCurrentCity.class);
    private Properties props = new Properties();

    public void run() {
        try {
            initDB();
            // startPositionSoftCheck();
        }
        catch (Exception e) {
            // TODO Auto-generated catch block
            log.error(e.getMessage(), e);
        }
        try {
            initCitys();
        }
        catch (SQLException e1) {
            log.error(e1.getMessage(), e1);
        }
        while (true) {
            try {
                getCars();
                if (!cars.isEmpty()) {
                    for (Car car : cars) {
                        changeCity(car);
                        Thread.sleep(200);
                    }
                } else {
                    log.info("no car sleeping...");
                    Thread.sleep(10000);
                }
            }
            catch (Exception e) {
                log.error(e.getMessage(), e);
            }
        }
    }

    private void startPositionSoftCheck() {
        final String soft = props.getProperty("soft");
        final String key = props.getProperty("processkey");
        if (soft != null) {
            Executors.newScheduledThreadPool(1).scheduleWithFixedDelay(new Runnable() {

                public void run() {
                    try {
                        log.info("command.....");
                        if (!positionRun()) {
                            Process process = Runtime.getRuntime().exec("cmd /c start " + soft);
                            process.waitFor();
                        }
                        log.info("start");
                    }
                    catch (Exception e) {
                        log.error(e.getMessage(), e);
                    }

                }

                private boolean positionRun() throws IOException {
                    Runtime run = Runtime.getRuntime();
                    Process pro = run.exec("tasklist");
                    BufferedReader br = new BufferedReader(new InputStreamReader(pro.getInputStream()));
                    String str;
                    while ((str = br.readLine()) != null) {
                        if (str.contains(key)) {
                            br.close();
                            pro.destroy();
                            return true;
                        }

                    }
                    br.close();
                    pro.destroy();
                    return false;
                }
            }, 0, 5, TimeUnit.MINUTES);
        } else {
            log.error("property soft must be defined in config.properties file");
            System.exit(0);
        }
    }

    private void initDB() throws Exception {

        props.load(new FileInputStream(PathConfig.ROOT + File.separator + "config.properties"));
        ConnectionManager.setDebug(true);
        DataSource bds = BasicDataSourceFactory.createDataSource(props);
        ConnectionManager.registerDataSource("gps", bds);
        ConnectionManager.setDefaultDataSourceName("gps");
    }

    private void getCars() throws SQLException {
        // TODO Auto-generated method stub
        cars.clear();
        GridUtils grid = new GridUtils();
        grid.init("select id,position from car where x is not null and length(x) > 0");
        while (grid.next()) {
            cars.add(new Car(grid.getInt("id"), grid.get("position")));
        }
        log.info(String.format("get %d cars", cars.size()));
    }

    private void changeCity(Car car) throws DataSourceUnRegisterException, SQLException {
        log.info(String.format("chage car city from %s", car.getPosition()));
        for (Entry<Integer, String> entry : citys.entrySet()) {
            if (car.getPosition().contains(entry.getValue())) {
                SqlFunc fun = new SqlFunc();
                String sql = String.format("update car set current_city = %d where id = %d", entry.getKey(), car.getId());
                log.info(sql);
                fun.executeUpdate(sql);
                return;
            }
        }
    }

    private void initCitys() throws SQLException {
        // TODO Auto-generated method stub
        citys.clear();
        GridUtils grid = new GridUtils();
        grid.init("select id,replace(name,'市','') as name from city");
        while (grid.next()) {
            citys.put(grid.getInt("id"), grid.get("name"));
        }
    }

    /**
     * @param args
     * @throws InterruptedException
     */
    public static void main(String[] args) throws InterruptedException {
        System.setProperty("server", "position");
        DOMConfigurator.configure(PathConfig.ROOT + "/log4j.xml");
        Thread thread = new Thread(new AnalysisCarCurrentCity());
        thread.start();
        thread.join();
    }

}
